﻿using System;
using System.Linq;
using System.Reflection.Emit;
using msilgc.cbuilder.CSyntaxTree;
using msilgc.cbuilder.MSILSyntaxTree;
using msilgc.CSyntaxTree;

namespace msilgc.cbuilder.CBuilder
{
    internal class LoadLocalTranslator : ITranslator {
        private readonly VariableFactory _varFactory;

        public LoadLocalTranslator(VariableFactory varFactory) {
            _varFactory = varFactory;
        }

        private static IVariable FindLocalVariable(CMethodBody methodBody, Instruction instruction) {
            if(instruction.Inst == OpCodes.Ldloc_0) {
                return methodBody.LocalVariables.ElementAt(0);
            }
            if(instruction.Inst == OpCodes.Ldloc_1) {
                return methodBody.LocalVariables.ElementAt(1);
            }
            if(instruction.Inst == OpCodes.Ldloc_2) {
                return methodBody.LocalVariables.ElementAt(2);
            }
            if(instruction.Inst == OpCodes.Ldloc_3) {
                return methodBody.LocalVariables.ElementAt(3);
            }
            if(instruction.Inst == OpCodes.Ldloc_S) {
                return methodBody.LocalVariables.ElementAt(instruction.Data.ElementAt(0));
            }
            throw new Exception("unexpected instruction: " + instruction);
        }

        public ICStatement TranslateAndAdd(CMethodBody methodBody, CBasicBlock currentBlock, BasicBlock block, Instruction instruction) {
            IVariable localVar = FindLocalVariable(methodBody, instruction);
            AssignToLocalVariable stm = new AssignToLocalVariable(localVar, _varFactory.CreateNext(localVar.Type));
            currentBlock.Statements.Add(stm);
            return stm;
        }
    }
}